using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using SIOGDE.AccesoDatos.Entidades;
using SIOGDE.AccesoDatos.Contratos;
using SIOGDE.Negocios.Servicios;
using SIOGDE.Negocios.Excepciones;
using Didsoft.DUA.AccesoDatos.Entidades;
using Didsoft.Core.Data;
using SIOGDE.AccesoDatos.Entidades.Lites;
using System.Net.Mail;
using SIOGDE.AccesoDatos.Entidades.Reportes;

namespace SIOGDE.Negocios
{
   /// <summary>
   /// Implementacion de la interface IPersonaNegociosServicio, los metodos que estan definidos en el contrato IPersonaNegociosServicio serán accesibles desde un contexto externo
   /// </summary>	
   public class PersonaNegocios : IPersonaNegociosServicio
   {
	private IPersonaAccesoDatos accesoDatos;
	public PersonaNegocios()
	{		
		accesoDatos = DataFactory.Current.GetPersonaAccesoDatos();
	}
	
	/// <summary>
    /// Devuelve una lista de Persona's de las ocurrencias encontradas a partir del filtro
    /// </summary>    
	public List<Persona> BuscarPorFiltro(string filtro)
	{
		return accesoDatos.BuscarPorFiltro(filtro).ToList();
	}

    public DataPager<Persona> PaginarPorFiltro(string filtro, int filas, int numPagina)
    {
        return accesoDatos.PaginarPorFiltro(filtro, filas, numPagina);
    }

    public List<Persona> BuscarPorFiltro(string nombres, string apellidoPaterno, string apellidoMaterno)
    {
        return accesoDatos.BuscarPorFiltro(nombres, apellidoPaterno, apellidoMaterno).ToList();
    }



	#region operaciones básicas
	
	/// <summary>
    /// Elimina la entidad Persona, lanzará una excepcion si la entidad guarda dependencia a otras entidades
    /// </summary>	
	public void Eliminar(Persona entidad)
	{
		try
		{
		    accesoDatos.Delete(accesoDatos.GetById(entidad.Id));
	    }
		catch(Exception ex)
		{
		   throw new PersonaEliminarExcepcion("Persona");
		}
	}
	
	/// <summary>
    /// Devuelve Persona, buscada por su Id, si no existe, entonces devuelve null
    /// </summary>	
	public Persona ObtenerPorId(object Id)
	{
		return accesoDatos.GetById(Id);
	}

    public Persona GetByGuid(string guid)
    {
        return accesoDatos.GetByGuid(guid);
    }

	/// <summary>
    /// Devuelve List<Persona>, de todas la entidades de ese tipo
    /// </summary>	
	public List<Persona> ObtenerTodas()
	{
		return accesoDatos.GetAll().ToList();
	}

	
	/// <summary>
    /// Guarda Persona, previa ejecucion satisfactoria de las reglas de negocio
    /// </summary>	
	public Persona Guardar(Persona entidad)
	{
		//Agregar aqui las reglas de negocio.......	
		if(entidad==null)
		 throw new PersonaRequeridoExcepcion();


        entidad.FechaNacimiento = DateFormatter.CastToDateNullable(entidad.FechaNacimientoString);
        entidad.FechaEgreso = DateFormatter.CastToDateNullable(entidad.FechaEgresoString);

       

        //if (!string.IsNullOrEmpty(entidad.FechaNacimientoString))
        //{
        //    var splitedFNac = entidad.FechaNacimientoString.Split('/');
        //    if(splitedFNac.Count()==3)
        //       entidad.FechaNacimiento = new DateTime(Convert.ToInt32(splitedFNac[2]), Convert.ToInt32(splitedFNac[1]), Convert.ToInt32(splitedFNac[0]));
        //    else
        //      entidad.FechaNacimiento = null;
        //}
        //if (!string.IsNullOrEmpty(entidad.FechaEgresoString))
        //{            
        //    var splitedFNac = entidad.FechaEgresoString.Split('/');
        //    if (splitedFNac.Count() == 3)
        //        entidad.FechaEgreso = new DateTime(Convert.ToInt32(splitedFNac[2]), Convert.ToInt32(splitedFNac[1]), Convert.ToInt32(splitedFNac[0]));
        //    else
        //        entidad.FechaEgreso = null;
        //}
        
        



		#region Foreign Keys Values
        if(entidad.PersonaConyugeId_FK > 0 && entidad.PersonaConyuge==null)
               entidad.PersonaConyuge = DataFactory.Current.GetPersonaAccesoDatos().GetById(entidad.PersonaConyugeId_FK);
        #endregion

        if (string.IsNullOrEmpty(entidad.Guid))
            entidad.Guid = System.Guid.NewGuid().ToString();


        accesoDatos.BeginTransaction();
        try
        {

            if (entidad.Id == 0)
            {
                accesoDatos.Insert(entidad);
                CrearUsuario(entidad);
            }
            else
                accesoDatos.Update(entidad);

            accesoDatos.CommitTransaction();
        }
        catch (Exception e)
        {
            accesoDatos.RollbackTransaction();
            throw e;
        }
        
		return entidad;
	}


    public void CrearUsuario(Persona entidad)
    {
        /**************   crear usuario por defecto ***************/

        Didsoft.DUA.Negocios.DUA_UsuarioNegocios usuarioNegocios = new Didsoft.DUA.Negocios.DUA_UsuarioNegocios();
        DUA_Usuario usuario = new DUA_Usuario();
        usuario.Rol = new DUA_Rol() { Id = 6 };

        string guidUs = string.Empty;
        string guidPass = string.Empty;
        if (string.IsNullOrEmpty(entidad.CI))
        {
            guidUs = System.Guid.NewGuid().ToString();
            guidUs = guidUs.Replace("-", "");
            guidUs = guidUs.Substring(0, 10);
        }
        else
        {
            guidUs = entidad.CI.Replace(" ", "");
        }

        usuario.Nombre = guidUs;
        guidPass = System.Guid.NewGuid().ToString();
        guidPass = guidPass.Replace("-", "");
        guidPass = guidPass.Substring(0, 10);
        usuario.Contrasena = guidPass;

        usuario.Persona = entidad;
        usuario.PreguntaSeguridad = entidad.NombreCompleto;
        usuario.RespuestaSeguridad = entidad.NombreCompleto;
        usuarioNegocios.Guardar(usuario);

        /**************   end creacion de usuario ***************/
    }


	#endregion

    public void EnviarEmail(string personaGuid, string email)
    {
        Persona persona = accesoDatos.GetByGuid(personaGuid);
        DUA_Usuario usuario = Didsoft.DUA.AccesoDatos.Contratos.DataFactory.Current.GetDUA_UsuarioAccesoDatos().GetUsuariosPorPersonaGuid(personaGuid).FirstOrDefault();
        try
        {
            //favor aplicar formato/estilo al email enviado
            string htmlContent = string.Format(@"<html>
                                    <body>
                                    <h2>SISTEMA DE INFORMACION PARA LA ROTACION DEL PERSONAL DEL EJERCITO</h2>
                                        Bienvenido, su cuenta esta apunto de activarse, para lo cual necesita acceder al sistema con las siguientes credenciales: <br>
                                        <ul>
                                            <li><a href='{0}' target='_blank'>Click aqui para acceder al Sistema</a></li>
                                            <li><b>Usuario : </b>{1}</li>
                                            <li><b>Contrasena : </b>{2}</li>
                                        </ul>
                                   </h1>
                                    <p>SIPRADE 2013 - Version de prueba - No Oficial</p>
                                   </body></html>", "http://192.168.0.2/SIPRE/", usuario.Nombre, usuario.Contrasena);


            Utils.EmailSender.SendEmail(new List<string>() { email }, "No Responder", htmlContent);
            
        }
        catch (Exception ex) { throw new Exception("Error al enviar email : " + ((ex.InnerException != null) ? ex.InnerException.Message : ex.Message)); }
    }


    /// <summary>
    /// used only for test, unit test email sender
    /// </summary>
    /// <param name="personaGuid"></param>
    /// <param name="email"></param>
    public void SendEmailWithoutThread(string personaGuid, string email)
    {
        Persona persona = accesoDatos.GetByGuid(personaGuid);
        DUA_Usuario usuario = Didsoft.DUA.AccesoDatos.Contratos.DataFactory.Current.GetDUA_UsuarioAccesoDatos().GetUsuariosPorPersonaGuid(personaGuid).FirstOrDefault();
        try
        {
            //favor aplicar formato/estilo al email enviado
            string htmlContent = string.Format(@"<html>
                                    <body>
                                    <h2>Credenciales</h2>
                                        Bienvenido, su cuenta esta apunto de activarse, para lo cual necesita acceder al sistema con las siguientes credenciales: <br>
                                        <ul>                                            
                                            <li><b>Usuario : </b>{0}</li>
                                            <li><b>Contrasena : </b>{1}</li>
                                        </ul>
                                   
                                    2013 - Version de prueba - {2}</p>
                                   </body></html>", usuario.Nombre, usuario.Contrasena, persona.NombreCompleto);


            Utils.EmailSender.SendEmailAlone(new List<string>() { email }, "No-Reply", htmlContent);

        }
        catch (Exception ex) { throw new Exception("Error al enviar email : " + ((ex.InnerException != null) ? ex.InnerException.Message : ex.Message)); }
    }

    public PersonalInfo GetInfoPersonal()
    {
        int PersonaIdSession = SIOGDE.Negocios.Global.Session.UserInfo.Persona.Id;
        int GestionId = SIOGDE.Negocios.Global.Session.GestionActiva.Id;

        return GetInfoPersonal(PersonaIdSession, GestionId);
    }

    public PersonalInfo GetInfoPersonal(int personaId, int gestionId)
    {
        PersonalInfo info = new PersonalInfo();

        int PersonaIdSession = personaId;
        int GestionId = gestionId;

        info.Arma = DataFactory.Current.GetArmaAccesoDatos().GetPorPersonaId(PersonaIdSession);
        info.Destino = DataFactory.Current.GetDestinoAsignadoAccesoDatos().GetPorPersonaId(PersonaIdSession, GestionId);

        info.Destino = info.Destino == null ? new DestinoAsignado() { RequerimientoConfig = new RequerimientoConfig() { UnidadMilitar = new UnidadMilitar() { Nombre = "" } } } : info.Destino;

        var especialidades = DataFactory.Current.GetEspecialidadAccesoDatos().GetPorPersonaId(PersonaIdSession).ToList();

        info.Especialidades = especialidades.Count > 0 ? especialidades : new List<Especialidad>() { new Especialidad() { Nombre = "-" } };
        info.Grado = DataFactory.Current.GetGradoAccesoDatos().GetPorPersonaId(PersonaIdSession);
        info.Persona = SIOGDE.Negocios.Global.Session.UserInfo.Persona;

        return info;
    
    }

    #region Reporte

    public List<DTORolUsuario> GetUsuariosPorRol(List<int> rolIds)
    {
        return accesoDatos.GetRolUsuarios(rolIds).ToList();
    }

	#endregion
       

   }


}


